Skip to content

Release Codex lifecycle hooks 0.3.6 - #14

Merged
TerminallyLazy merged 2 commits into
mainfrom
codex/lifecycle-hooks-release
Sep 8, 2026
Merged

Release Codex lifecycle hooks 0.3.6#14
TerminallyLazy merged 2 commits into
mainfrom
codex/lifecycle-hooks-release

Conversation

@TerminallyLazy

@TerminallyLazy TerminallyLazy commented Sep 8, 2026

Copy link
Copy Markdown
Owner

Ship native SessionStart/SubagentStart recall and Stop/SubagentStop capture checkpoints in the Git marketplace package. Startup recall now uses CLI 0.15.7 for cross-session project and agent visibility, bounded context, and project-local executable resolution. Managed project hooks take precedence to avoid duplicate recall and checkpoints.

Codex package 0.3.6 includes a root marketplace entry and hook definitions accepted by Codex 0.151. Public-directory ZIPs remain an explicit skills-only build with a distinct manifest; they do not promise automatic hooks.

Validation: package and lifecycle forwarding checks pass, and the real CLI smoke passes. CI installs the checksum-pinned 0.15.7 Linux release.

High-level PR Summary

This release ships version 0.3.6 of the Tree Ring Memory Codex plugin, introducing native lifecycle hooks for automatic session-start recall and stop-event memory checkpoints. The plugin now registers SessionStart, SubagentStart, Stop, and SubagentStop hooks that forward lifecycle events to the Tree Ring Memory CLI (0.15.7). Key features include project-local executable resolution, bounded context loading, agent-mediated checkpointing at stop events, and managed-hook ownership detection to prevent duplicate invocations. The package adds a marketplace entry for Git-based distribution while maintaining a separate skills-only build for directory uploads that excludes hooks.

⏱️ Estimated Review Time: 15-30 minutes

💡 Review Order Suggestion
Order File Path
1 .codex-plugin/plugin.json
2 hooks/codex-hooks.json
3 hooks/codex-hook.sh
4 packaging/codex-skills-only/.codex-plugin/plugin.json
5 packaging/build-codex-skills-only.py
6 .agents/plugins/marketplace.json
7 .github/workflows/validate.yml
8 scripts/validate-lifecycle.py
9 scripts/validate-plugin.sh
10 scripts/smoke_v015.sh
11 skills/tree-ring-memory/SKILL.md
12 README.md
13 PRIVACY.md
14 TERMS.md
15 SECURITY.md
16 SUBMISSION.md

Need help? Join our Discord

@coderabbitai

coderabbitai Bot commented Sep 8, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 76d15c7d-770d-41d7-b98e-f1999a359187


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Release native Codex lifecycle hooks in plugin 0.3.6

✨ Enhancement 🧪 Tests 📝 Documentation ⚙️ Configuration changes 🕐 40+ Minutes

Grey Divider

AI Description

• Adds native start recall and stop capture hooks to the repository marketplace plugin.
• Prefers managed project hooks and project-local CLI resolution to prevent duplicate lifecycle
 handling.
• Preserves a deterministic skills-only ZIP and validates CLI 0.15.7 integration.
Diagram

sequenceDiagram
    actor Host as Codex Host
    participant Config as Hook Config
    participant Wrapper as Hook Wrapper
    participant Marker as Managed Marker
    participant CLI as Tree Ring CLI
    participant Store as Local Memory
    Host->>Config: Lifecycle event
    Config->>Wrapper: Forward event JSON
    Wrapper->>Wrapper: Resolve project root
    Wrapper->>Marker: Check managed ownership
    alt Managed hook exists
        Wrapper-->>Host: Skip duplicate handling
    else Marketplace owns event
        Wrapper->>CLI: Forward JSON through stdin
        alt Start event
            CLI->>Store: Recall bounded context
            Store-->>CLI: Return scoped memories
            CLI-->>Host: Supply additional context
        else Stop event
            CLI-->>Host: Request capture checkpoint
            Host->>CLI: Submit approved candidate
            CLI->>Store: Persist strict capture
        end
    end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Require CLI-managed project hooks only
  • ➕ Eliminates marketplace and project hook overlap entirely
  • ➕ Keeps lifecycle ownership in one generated configuration
  • ➖ Requires explicit activation in every project
  • ➖ Removes automatic lifecycle behavior from repository plugin installs
2. Publish one hook-capable ZIP artifact
  • ➕ Reduces packaging profiles and release artifact complexity
  • ➕ Keeps repository and directory manifests identical
  • ➖ Conflicts with public-directory package constraints
  • ➖ Could imply automatic hooks where the upload channel cannot provide them

Recommendation: Keep the PR's split-distribution approach. The marketplace wrapper provides native lifecycle behavior while managed-hook detection prevents duplicate processing, and the dedicated deterministic ZIP accurately preserves the public directory's skills-only contract.

Files changed (16) +519 / -32

Enhancement (3) +85 / -3
plugin.jsonRelease plugin 0.3.6 with lifecycle hooks +4/-3

Release plugin 0.3.6 with lifecycle hooks

• Bumps the repository plugin to 0.3.6, registers the Codex hook definition, and points legal links to the canonical repository paths.

.codex-plugin/plugin.json

codex-hook.shAdd the Codex lifecycle command wrapper +26/-0

Add the Codex lifecycle command wrapper

• Resolves the Git project root, suppresses execution when supported managed project hooks exist, prefers the project-local executable, and forwards stdin to the Codex lifecycle CLI entry point.

hooks/codex-hook.sh

codex-hooks.jsonRegister Codex start and stop lifecycle events +55/-0

Register Codex start and stop lifecycle events

• Defines synchronous ten-second handlers for SessionStart, SubagentStart, Stop, and SubagentStop. Start handlers additionally cap injected context at 6,000 units.

hooks/codex-hooks.json

Tests (3) +156 / -3
smoke_v015.shUpdate the real CLI smoke test to 0.15.7 +1/-1

Update the real CLI smoke test to 0.15.7

• Changes the expected installed Tree Ring CLI version from 0.15.0 to 0.15.7.

scripts/smoke_v015.sh

validate-lifecycle.pyValidate lifecycle packaging and forwarding contracts +151/-0

Validate lifecycle packaging and forwarding contracts

• Checks exact event registration, timeout and context limits, executable resolution, byte-preserving stdin forwarding, CLI arguments, output forwarding, and managed-hook ownership behavior.

scripts/validate-lifecycle.py

validate-plugin.shValidate release version and lifecycle package +4/-2

Validate release version and lifecycle package

• Updates the expected wrapper version to 0.3.6 and runs the new lifecycle validation as part of the plugin contract checks.

scripts/validate-plugin.sh

Documentation (6) +158 / -24
PRIVACY.mdDocument lifecycle-hook privacy boundaries +26/-8

Document lifecycle-hook privacy boundaries

• Explains synchronous event forwarding, excluded transcript fields, strict capture gates, and local-only memory storage for the hook-capable package.

PRIVACY.md

README.mdDocument hook-capable installation and lifecycle behavior +72/-2

Document hook-capable installation and lifecycle behavior

• Adds marketplace installation instructions and describes start recall, stop checkpoints, project-local CLI resolution, managed-hook precedence, receipt interpretation, and skills-only artifact boundaries.

README.md

SECURITY.mdDefine lifecycle hook security constraints +14/-3

Define lifecycle hook security constraints

• Documents the four supported events, ten-second synchronous limit, non-persistence guarantees, and strict normal-sensitivity capture requirements.

SECURITY.md

SUBMISSION.mdSeparate repository hooks from directory distribution +10/-1

Separate repository hooks from directory distribution

• Updates release notes to 0.3.6 and clarifies that Git marketplace distribution includes hooks while directory submissions remain separately versioned skills-only ZIPs.

SUBMISSION.md

TERMS.mdExtend terms to cover local lifecycle hooks +7/-6

Extend terms to cover local lifecycle hooks

• Distinguishes the hook-capable repository plugin from the skills-only upload and assigns users responsibility for reviewing hook trust and local access.

TERMS.md

SKILL.mdTeach agents the automatic lifecycle checkpoint contract +29/-4

Teach agents the automatic lifecycle checkpoint contract

• Adds CLI compatibility and receipt guidance, explains bounded start recall and stop checkpoints, and requires supplied strict capture templates for grounded normal-sensitivity candidates.

skills/tree-ring-memory/SKILL.md

Other (4) +120 / -2
marketplace.jsonAdd the root Git marketplace entry +20/-0

Add the root Git marketplace entry

• Defines Tree Ring Memory as a locally sourced developer-tools plugin with installation and authentication policies for marketplace discovery.

.agents/plugins/marketplace.json

validate.ymlPin CI validation to Tree Ring CLI 0.15.7 +2/-2

Pin CI validation to Tree Ring CLI 0.15.7

• Updates the validation environment and checksum to install the verified Linux release of Tree Ring Memory CLI 0.15.7.

.github/workflows/validate.yml

build-codex-skills-only.pyAdd deterministic skills-only ZIP packaging +50/-0

Add deterministic skills-only ZIP packaging

• Builds a reproducible public-directory archive containing the alternate manifest, skills, assets, license, and policy documents while excluding lifecycle hooks.

packaging/build-codex-skills-only.py

plugin.jsonAdd the skills-only 0.3.6 manifest +48/-0

Add the skills-only 0.3.6 manifest

• Defines a distinct Codex manifest for public-directory uploads without a hooks registration, while retaining skills and interface metadata.

packaging/codex-skills-only/.codex-plugin/plugin.json

@TerminallyLazy
TerminallyLazy merged commit c25a314 into main Sep 8, 2026
4 checks passed
@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (3) 📘 Rule violations (0) 📜 Skill insights (0)

Grey Divider


Action required

1. Lifecycle validation never runs in CI 🐞 Bug ☼ Reliability
Description
load_json annotates its return type with Any, but scripts/validate-lifecycle.py neither
imports it from typing nor postpones annotation evaluation, so Python raises NameError while
defining the function. Every package validation run reaches this script through
validate-plugin.sh, so CI stops before lifecycle configuration, packaged-hook forwarding, or other
lifecycle assertions execute.
Code

scripts/validate-lifecycle.py[8]

+def load_json(path: Path) -> dict[str, Any]:
Evidence
The module imports json, os, subprocess, tempfile, and Path, but then evaluates `dict[str,
Any] without defining Any`. The package validator invokes this lifecycle validator
unconditionally, and the GitHub workflow runs that package validation script, proving the undefined
annotation blocks validation during module initialization.

scripts/validate-lifecycle.py[3-8]
scripts/validate-plugin.sh[92-94]
.github/workflows/validate.yml[58-59]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The lifecycle validator references `Any` in a runtime-evaluated return annotation without importing it, causing an immediate `NameError` during module initialization.

## Issue Context
`scripts/validate-plugin.sh` always executes this validator as part of the repository's package validation workflow, so CI fails before lifecycle configuration, packaged-hook forwarding, or other lifecycle assertions run. Import `Any` from `typing`, or postpone annotation evaluation and use an available type.

## Fix Focus Areas
- scripts/validate-lifecycle.py[3-8]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. Projects can lose automatic memory checks 🐞 Bug ≡ Correctness
Description
codex-hook.sh treats any occurrence of a managed-lifecycle marker string in .codex/hooks.json as
proof that an active managed hook owns the events. A project configuration that merely includes that
text in an unrelated description or value makes the marketplace hook exit before invoking the CLI,
leaving recall and stop checkpoints unavailable.
Code

hooks/codex-hook.sh[R13-18]

+if [ -f .codex/hooks.json ] && {
+    grep -Fq 'Tree Ring Memory managed lifecycle v2"' .codex/hooks.json ||
+        grep -Fq 'Tree Ring Memory managed lifecycle v3"' .codex/hooks.json ||
+        grep -Fq 'Tree Ring Memory managed lifecycle v4"' .codex/hooks.json
+}; then
+    exit 0
Evidence
The shell wrapper performs only raw fixed-string searches and immediately exits on a match. The
documented ownership rule applies when project activation has installed the managed lifecycle
definition, while the added validator tests only positive marker files and does not reject unrelated
occurrences.

hooks/codex-hook.sh[13-19]
README.md[255-260]
scripts/validate-lifecycle.py[112-130]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The marketplace wrapper disables itself based on an unstructured substring match anywhere in `.codex/hooks.json`, rather than confirming that the managed lifecycle definition is present and owns the relevant hook events.

## Issue Context
The wrapper exits before calling the lifecycle CLI. Documentation says this stand-down behavior is intended only when project activation installed the managed lifecycle definition.

## Fix Focus Areas
- hooks/codex-hook.sh[13-18]
- scripts/validate-lifecycle.py[112-147]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Users reach incorrect legal pages 🐞 Bug ≡ Correctness
Description
The changed plugin manifest sends privacy and terms users to a plugins/tree-ring-memory path in
the separate framework repository, while the package's published submission identifies the plugin
repository's root legal documents. The skills-only manifest duplicates those legal URLs and
additionally points its repository field at the framework rather than the published plugin source,
so both distribution forms expose inconsistent package provenance and policy links.
Code

.codex-plugin/plugin.json[R38-39]

+    "privacyPolicyURL": "https://github.com/TerminallyLazy/Tree-Ring-Memory/blob/main/plugins/tree-ring-memory/PRIVACY.md",
+    "termsOfServiceURL": "https://github.com/TerminallyLazy/Tree-Ring-Memory/blob/main/plugins/tree-ring-memory/TERMS.md",
Evidence
The main manifest's changed policy links target the framework repository's nested plugin path, and
the new ZIP manifest contains the same links plus a framework repository source field. The package
submission instead identifies this plugin repository and its root privacy and terms pages; the ZIP
builder also packages those legal files from this repository root.

.codex-plugin/plugin.json[37-39]
packaging/codex-skills-only/.codex-plugin/plugin.json[9-10]
packaging/codex-skills-only/.codex-plugin/plugin.json[36-38]
SUBMISSION.md[9-13]
packaging/build-codex-skills-only.py[38-39]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The repository plugin manifest now points legal-policy links at a different repository path than the source and legal documents declared for this package. The separately generated skills-only manifest repeats these policy URLs and declares the framework repository as its package source.

## Issue Context
The submission material identifies the plugin repository and root-level privacy and terms documents as the published locations. Keep the repository and policy metadata consistent across both manifest variants.

## Fix Focus Areas
- .codex-plugin/plugin.json[38-39]
- packaging/codex-skills-only/.codex-plugin/plugin.json[9-10]
- packaging/codex-skills-only/.codex-plugin/plugin.json[36-38]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context sources
Review mode: 🧠 Deep: This release adds security- and privacy-sensitive lifecycle hooks, CLI forwarding, managed-hook precedence, packaging variants, and validation across multiple independent code paths, creating substantial opportunity for subtle defects.

Grey Divider

Tip of the day
💡 Did you know, you can tweak Display preferences with a live preview to see your comment before it ships

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

ROOT = Path(__file__).resolve().parents[1]
LIFECYCLE_EVENTS = {"SessionStart", "SubagentStart", "Stop", "SubagentStop"}

def load_json(path: Path) -> dict[str, Any]:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

1. Lifecycle validation never runs in ci 🐞 Bug ☼ Reliability

load_json annotates its return type with Any, but scripts/validate-lifecycle.py neither
imports it from typing nor postpones annotation evaluation, so Python raises NameError while
defining the function. Every package validation run reaches this script through
validate-plugin.sh, so CI stops before lifecycle configuration, packaged-hook forwarding, or other
lifecycle assertions execute.
Agent Prompt
## Issue description
The lifecycle validator references `Any` in a runtime-evaluated return annotation without importing it, causing an immediate `NameError` during module initialization.

## Issue Context
`scripts/validate-plugin.sh` always executes this validator as part of the repository's package validation workflow, so CI fails before lifecycle configuration, packaged-hook forwarding, or other lifecycle assertions run. Import `Any` from `typing`, or postpone annotation evaluation and use an available type.

## Fix Focus Areas
- scripts/validate-lifecycle.py[3-8]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment thread hooks/codex-hook.sh
Comment on lines +13 to +18
if [ -f .codex/hooks.json ] && {
grep -Fq 'Tree Ring Memory managed lifecycle v2"' .codex/hooks.json ||
grep -Fq 'Tree Ring Memory managed lifecycle v3"' .codex/hooks.json ||
grep -Fq 'Tree Ring Memory managed lifecycle v4"' .codex/hooks.json
}; then
exit 0

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

2. Projects can lose automatic memory checks 🐞 Bug ≡ Correctness

codex-hook.sh treats any occurrence of a managed-lifecycle marker string in .codex/hooks.json as
proof that an active managed hook owns the events. A project configuration that merely includes that
text in an unrelated description or value makes the marketplace hook exit before invoking the CLI,
leaving recall and stop checkpoints unavailable.
Agent Prompt
## Issue description
The marketplace wrapper disables itself based on an unstructured substring match anywhere in `.codex/hooks.json`, rather than confirming that the managed lifecycle definition is present and owns the relevant hook events.

## Issue Context
The wrapper exits before calling the lifecycle CLI. Documentation says this stand-down behavior is intended only when project activation installed the managed lifecycle definition.

## Fix Focus Areas
- hooks/codex-hook.sh[13-18]
- scripts/validate-lifecycle.py[112-147]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment thread .codex-plugin/plugin.json
Comment on lines +38 to +39
"privacyPolicyURL": "https://github.com/TerminallyLazy/Tree-Ring-Memory/blob/main/plugins/tree-ring-memory/PRIVACY.md",
"termsOfServiceURL": "https://github.com/TerminallyLazy/Tree-Ring-Memory/blob/main/plugins/tree-ring-memory/TERMS.md",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

3. Users reach incorrect legal pages 🐞 Bug ≡ Correctness

The changed plugin manifest sends privacy and terms users to a plugins/tree-ring-memory path in
the separate framework repository, while the package's published submission identifies the plugin
repository's root legal documents. The skills-only manifest duplicates those legal URLs and
additionally points its repository field at the framework rather than the published plugin source,
so both distribution forms expose inconsistent package provenance and policy links.
Agent Prompt
## Issue description
The repository plugin manifest now points legal-policy links at a different repository path than the source and legal documents declared for this package. The separately generated skills-only manifest repeats these policy URLs and declares the framework repository as its package source.

## Issue Context
The submission material identifies the plugin repository and root-level privacy and terms documents as the published locations. Keep the repository and policy metadata consistent across both manifest variants.

## Fix Focus Areas
- .codex-plugin/plugin.json[38-39]
- packaging/codex-skills-only/.codex-plugin/plugin.json[9-10]
- packaging/codex-skills-only/.codex-plugin/plugin.json[36-38]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant